//
//  overlays.swift
//  amap
//
//  Created by James Karl on 2020/5/11.
//

import Foundation
import MAMapKit

protocol MapOverlay {
    func createRenderer() -> MAOverlayRenderer?
}

class CircleOverlay : MACircle , MapOverlay {
    let options: CircleOptionsData
    
    init?(_ options: CircleOptionsData) {
        self.options = options
        if let center = options.center?.toMapPoint(), let radius = options.radius {
            super.init()
            setCircleWithCenterCoordinate(center, radius: radius)
        } else {
            return nil
        }
    }
    
    func createRenderer() -> MAOverlayRenderer? {
        if let renderer = MACircleRenderer(overlay: self) {
            if let strokeWidth = options.strokeWidth {
                renderer.lineWidth = CGFloat(strokeWidth)
            }
            if let strokeColor = options.strokeColor {
                renderer.strokeColor = strokeColor.toUIColor()
            }
            if let fillColor = options.fillColor {
                renderer.fillColor = fillColor.toUIColor()
            }
            return renderer
        } else {
            return nil
        }
    }
    
}

class PolylineOverlay : MAPolyline, MapOverlay {
    let options: PolylineOptionsData
    
    init?(options: PolylineOptionsData) {
        self.options = options
        if var points = options.points?.map({p in p.toMapPoint()}) {
            super.init()
            super.setPolylineWithCoordinates(&points, count: points.count)
        } else {
            return nil
        }
        
    }
    
    func createRenderer() -> MAOverlayRenderer? {
        if let renderer = MAPolylineRenderer(polyline: self) {
            if let lineWidth = options.width {
                renderer.lineWidth  = CGFloat(lineWidth)
            }
            if let color = options.color {
                renderer.strokeColor = color.toUIColor()
            }
            return renderer
        } else {
            return nil
        }
    }
}

class MapAnnotation : MAPointAnnotation {
    private let options: AnnotationViewData
    
    init?(options: AnnotationViewData) {
        self.options = options
        if let position = options.position?.toMapPoint() {
            super.init()
            super.coordinate = position
            
            if let title = options.title {
                super.title = title
            }
            
            if let snippet = options.snippet {
                super.subtitle = snippet
            }
        } else {
            return nil
        }
    }
    
    func createAnnotationView(mapView: MAMapView, registrar: FlutterPluginRegistrar) -> MAAnnotationView? {
        if PlatformMapView.annotationFactory != nil {
            if let view = PlatformMapView.annotationFactory?.create(mapView, registrar, options) {
                return view
            }
        }
        if options.icon != nil {
            return createCustomAnnotationView(mapView: mapView, registrar: registrar)
        } else {
            return createPinAnnotationView(mapView: mapView, registrar: registrar)
        }
    }
    
    private func createPinAnnotationView(mapView: MAMapView, registrar: FlutterPluginRegistrar) -> MAAnnotationView? {
        let pointReuseIndetifier = "pointReuseIndetifier"
        
        var annotationView: MAPinAnnotationView? = mapView.dequeueReusableAnnotationView(withIdentifier: pointReuseIndetifier) as! MAPinAnnotationView?
        
        if annotationView == nil {
            annotationView = MAPinAnnotationView(annotation: self, reuseIdentifier: pointReuseIndetifier)
        }
        
        annotationView!.canShowCallout = true
        annotationView!.animatesDrop = true
        annotationView!.isDraggable = true
        annotationView!.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
        
        return annotationView!
    }
    
    private func createCustomAnnotationView(mapView: MAMapView, registrar: FlutterPluginRegistrar) -> MAAnnotationView? {
        let customReuseIndetifier: String = "customReuseIndetifier"
        
        var annotationView: MAAnnotationView? = mapView.dequeueReusableAnnotationView(withIdentifier: customReuseIndetifier)
        
//        if annotationView == nil  || options.rotateAngle != nil {
            annotationView = MAAnnotationView.init(annotation: self, reuseIdentifier: customReuseIndetifier)
            annotationView?.canShowCallout = false
            annotationView?.isDraggable = true
            annotationView?.calloutOffset = CGPoint.init(x: 0, y: -5)
//        }
        
        if let zIndex = options.zIndex {
            annotationView?.zIndex = Int(zIndex)
        }
        
        if let iconName = options.icon {
            //let filename = registrar.lookupKey(forAsset: iconName)
            if let rotateAngle = options.rotateAngle {
                let transform = CGAffineTransform(rotationAngle: CGFloat(rotateAngle))
                let image = UIImage(named: iconName)
                let imageView = UIImageView(image: image)
                imageView.contentMode = .center
                imageView.transform = transform
                
                let delta = ((options.extra as? Double) ?? 7.0)
                imageView.center = (annotationView?.imageView.center)!
                imageView.center = CGPoint(x: (annotationView?.imageView.center.x)! - CGFloat(delta*sin(options.rotateAngle!)), y: (annotationView?.imageView.center.y)! + CGFloat(delta*cos(options.rotateAngle!)))
                
                annotationView?.addSubview(imageView)
            } else {
                annotationView!.image = UIImage(named: iconName)
            }
        }
        
        return annotationView!
    }
}

public protocol MapAnnotationFactory {
    func create(_ mapView: MAMapView, _ registrar: FlutterPluginRegistrar, _ options: AnnotationViewData) -> MAAnnotationView?
}
